/*
 * CStreamLayer.h
 *
 *  Created on: 2011-9-20
 *      Author: stargui
 */

#ifndef CSTREAMLAYER_H_
#define CSTREAMLAYER_H_

#include <list>
#include <map>
#include <string>
#include "CommonLibrary.h"
//#include <Message.h>
#include "ProtocolLabel.h"
#include "CProtocolFactory.h"
#include "CTaskSession.h"
#include "../SocketUtils/CPSocketUtils.h"
#include "../SocketUtils/CPSelectUtils.h"
#include "../SocketUtils/CMutexUtils.h"
#include "CSyncPlaybackStream.h"
#include "streambuffer/StreamBuffer.h"
#include <netinet/in.h>
#include "CTaskSession.h"
#include<ctime>
#include "../DataModel/GetFrameFromFile.h"
//#define  MAX_TASK_NODE		(MAX_ONLINE_USER_NUM * 4 + 30)
#include "Defines.h"
#include "ConfigJsonKeyword.h"
// #include "CommonLibrary.h"
#include  "Mediastream.h"
#include "Base.h"
#include "Certificate.h"
#include "Stun.h"
//#include "../DataModel/DataModel.h"
#include "../ThreadPool/ThreadPool.h"
#include "../MsgAndSem/AdpMsg.h"
#include <list>
#include <string>
using namespace Msg;
using namespace Frame_from_file;
using namespace std;
void* ThreadFun(void*);
bool write_to_client(int filedes, const void *buffer, size_t size);
typedef struct   video_info
{
		string name; //文件名
		long int starttime; // default 0 标志 从开始位置播放
		long int endtime;
}VIDEOINFO;
typedef struct channel_and_time
{                     //比如说 需要看 1通道 开始时间为 10：00 的录像视频
		unsigned int channel; 		//通道
		int				streamtype;//0:子码流,1:主码流
		datetime_t starttime; // default 0 标志 从开始位置播放
		datetime_t endtime;
}CHANEELANDTIME;
typedef struct _threadpara
{
	int socketfd;
	CHANEELANDTIME _channel_and_time;
}THREADPARA;
class CStreamLayer: public Common::CThread
{

public:

	CStreamLayer();

	virtual ~CStreamLayer();

	std::map<unsigned int, taskSession_node*> GetTaskList();


public:
	//sessid,socket,type,reponse
	//sessidΪ�û�sessoin��socket�����������̵߳�taskindex��reponse��Ӧ�����
	//typeΪ 0��ý�������ĵ�Ӧ��1��ý��֪ͨsession����ر�socket,����ֵ������
	void SetTaskSessionCallback(boost::function<bool(unsigned int, unsigned int, Json::Value &,int)> callback);


	void RequestRemotePlayback(Json::Value  request);

	void ControlRemotePlayback(Json::Value  request);


	taskSession_node* QuerySession(unsigned int ssid);

	//  i_taskhandle 套接字（已经建立好数路链路的套接字）
	// i_voide_list   客服端需要视频的链表
	// 返回值 0 表示成功 ，-1 标志失败   失败的具体的原因信息还有待商定
int datalink_interface(const int i_taskhandle,const channel_and_time remotequest);
//  i_taskhandle 同上
// i_cmd 命令标号 （和协议中定义相同）
//  i_optional_para 可选参数 （如鼠标拖拽后定位的时间等）
// 返回值 0 表示成功 -1 失败     失败的具体的原因信息还有待商定
int msglink_interface(const int i_taskhandle,int i_cmd,long int i_optional_para);

private:

	virtual void *ThreadFuncImpl();

public:

	int taskHandle,status;//socket,״̬

	unsigned int	taskindex,source;//������Ψһ,sessionid

	bool passiveMode;

	std::string taskName,sessionid,username,password;

	void *_threadid;

//	std::map<std::string, CRealStream* > _handleRealstream;

	int	 _linktype;//0:tcp,1:udp

private:

	boost::function<bool(unsigned int,unsigned int, Json::Value &,int)> _sessionCallback;

	std::map<unsigned int, taskSession_node*> myList;

	std::map<PAYLOAD_TYPE, boost::function<int(taskSession_node *)> > _operation;


	char	m_remoteplayback;	//ͬһ���û�����ͬʱ���ڶ���ط�����

	char	m_remoteplaybackchcount;//ͬ���ط�ͨ������


	CProtocolFactory m_packet;

	SShareMemData  m_pPack	;//ý�����ָ��

	std::string	m_ipport;//ý�������ip


private:



public:
	CMutexUtils _taskmutex;
private:


	int TimeStringToDateInfo(std::string timestring,DateInfo_Tag &datainfo);

	int StopNetServerAndSend(taskSession_node *currentsession);

	/*******************************************************************************Զ��ͬ���طŶ���************************************************************************************************/
	/******************************************************************************************************************************************************************************************/

	int CtrlRemotePlayback(taskSession_node *currentsession);

	int StartRemotePlaybackAndSend(unsigned int ssid,unsigned int channel,StreamType streamtype,VideoType videotype,DateInfo_Tag starttime,DateInfo_Tag endtime,taskSession_node*	currentsession);

	int GetRemotePalybackDataAndSend(taskSession_node *currentsession);

	/*******************************************************************************Զ��ͬ���طŶ���end*******************************************************************************/









private:
	/*******************************************************************************ý��ӿڶ���************************************************************************************************/
	/******************************************************************************************************************************************************************************************/
	//	�豸���������Զ�̶�·ͬ���طŽӿ�
	//Input param��
	//@ssid ��pt��ssrc��ϲ���Ψһ��id
	//@ startTime�طſ�ʼʱ��
	//@ endTime �طŽ���ʱ��
	//@ streamType �ط���Ƶ������
	//@ videotype ¼���ļ�����
	//@ chno�ط���Ƶ��ͨ���� bitλ��ʾ,bit0-bit31��ʾͨ��1-ͨ��32
	//	Return��0���ɹ���-1��ʧ��, 1: �������ط�������
 	int StartRemotePlayBack(const unsigned int ssid,unsigned int chno,StreamType streamType,VideoType videotype,DateInfo_Tag startTime,DateInfo_Tag endTime,taskSession_node*	currentsession);

	//�豸������ȡ��Ƶ���
	//Input param��@ ssid �ط�������
	//				@ channel ʵ��ͨ����
	//Outputparam��@ data ��ǰ��Ƶ���
	//formattype :��ݸ�ʽ 1���ļ�ͷ��0����Ч���
	//flag	: �Ƿ����µ����� 0�������� 1�����ο�ʼ 2:���ν���
	//Return��	0���ɹ���-1ʧ��,-2û�����, 1 ����, 2 ���ڽ���
	int GetRemotePlayBackData(taskSession_node*	currentsession,unsigned char **datafirst,int &datalenfirst,unsigned char **dataSecond,int &datalenSecond,int& formattype,int &freamtype,int &channel,unsigned int &flag,int &chnindex);

	//ȡ����ݺ���Ҫ�ͷ�
	int	ReleasePlayBackFream(taskSession_node*	currentsession,const int chnindex);

	//	�豸������ȡ����ͨ����Ƶ���״̬���е�ͨ������û��¼���е�ͨ����¼��ʵʱ����pc��ط�ʱ����ͨ����������Ƶ��״̬��
	//Input param��@ streamed �ط�������
	//				:@ channelmaskͨ�������룬bit0-bit31��ʾͨ��1-ͨ��32����ӦbitλΪ1ʱ��Ч
	//Outputparam��@ chnostate bitλ��ʾ��ǰ�ط������и���ͨ����״̬���������Ƶ�����Ϊ1��û����Ϊ0��Bit0-bit31��ʾͨ��1-ͨ��32
	//Return��	0���ɹ���-1ʧ��
	int GetRemotePlayBackChnoState(taskSession_node*	currentsession,unsigned int &chnostate,unsigned int channelmask);

	//�豸�������Զ�̶�·ͬ���ط�����״̬��
	//���ط���������ˣ���֪ͨ�����ط��������ͬʱ�����Ҳ��֪ͨpc�ϲ����ط�����
	//Input param��@ streamed �ط�������
	//Return�������0��δ�����-1
 	int CheckRemotePlayBackResult(taskSession_node*	currentsession);

	//	�������֪ͨ�豸�ײ�ֹͣ�ط�����
	//�豸������������쳣���߽��ܵ�ֹͣ��ָ����Զ��ͷ�������Դ��ͬʱҪ֪ͨ�豸�ײ��ͷŻط�ռ�õ���Դ��
	//Input param��@ streamed �ط�������
	//				@ channel ͨ����bitλ��ʾ
	//Return�� 0���ɹ��� -1��ʧ��
 	int StopRemotePlayBack(const unsigned int ssid,taskSession_node*	currentsession);

	//	�豸�������ק֪ͨ�豸
	//�ͻ����·�ָ����豸seek��ָ����λ�ã�Ҫ���豸��Ѹ�ٵ���Ӧ��������ʱ���豸������ʱӦ�ñ�֤��1-2S����ɣ��ڴ��õ������500ms�ھ������seek���������ǵ������ֶ����������£��豸���ػ�ܴ�seek����ʱҲ����Ӧ���ӳ��������뱣֤�ܾ����ܵ�Ѹ����Ӧ�������ڴ������ʱҲҪѸ�٣�����ʱ������͡�
	//Input param��@ currentsession �ط�����
	//			   @ SeekTimeʱ��
	//Return�� 0���ɹ��� -1��ʧ��
 	int SeekRemotePlayBack(taskSession_node*	currentsession,DateInfo_Tag SeekTime);

	//	�豸�������֪ͨ�豸
	//���������D1��¼���ļ���������������豸���紫�͵�������޷�����pc�ͻ��˿���ʣ��ʵ����������Ҫֻ�ϴ�I֡
	//��Ҫ��������4���ʣ��лطŵ�¼���ļ���������,����ȫ��p֡��
	//Input param��@ currentsession �ط�����
	//Return�� 0���ɹ��� -1��ʧ��
 	int ForwardRemotePlayBack(taskSession_node*	currentsession,int cmdtype);

	/******************************************************************************************************************************************************************************************/
	/*******************************************************************************ý��ӿڶ���************************************************************************************************/


};

#endif /* CSTREAMLAYER_H_ */
